﻿
#include "GActivityAncientElf.h"
#include "ServerModule/LogicActivityModule.h"
#include "Character/CreatureMgr.h"
#include "Character/monster/MonsterRefCfg.h"
#include "Character/npc/Npc.h"
#include "PlaneMgr/PlaneMgr.h"
#include "Duplicate/DuplicateMgr.h"
#include "Character/drop/DropMgr.h"
#include "Common/TableData/MonsterMonsterCfg.h"
#include "PlaneMgr/PlaneMgr.h"
#include "Common/TableData/AnswerAnswerCfg.h"
#include "Common/OperateLimitDefine.h"
#include "Answer/AnswerMgr.h"
#include "Character/HuoYueDuPart.h"
GActivityAncientElf::GActivityAncientElf()
{
	Clear();
	ClearUnionParam();
}

GActivityAncientElf::~GActivityAncientElf()
{

}

void GActivityAncientElf::Clear()
{
	m_cfg.clear();
	m_mapNpc.clear();
	m_mapMons.clear();
	memset(m_elfFreshNumAry, 0, sizeof(m_elfFreshNumAry));
	memset(m_elfNumAry, 0, sizeof(m_elfNumAry));
}

//清空工会参数
void GActivityAncientElf::ClearUnionParam()
{
	m_unionId = 0;
	m_sceneId = 0;
	m_mapId = 0;
	m_lev = 0;	
	m_averageLev = 0;
	m_collegaLev = 0;
}

Monster *GActivityAncientElf::GetSceneMonster(CharIDType cid)			//获取怪物
{
	return g_GetSceneMgr()->GetMonster(m_sceneId,cid);
}

Npc *GActivityAncientElf::GetSceneNpc(CharIDType cid)	//获取npc
{
	return g_GetSceneMgr()->GetNpc(m_sceneId, cid);
}

Player*GActivityAncientElf::GetScenePlayer(CharIDType cid) //获取玩家
{
	return g_GetSceneMgr()->GetPlayer(m_sceneId, cid);
}

void GActivityAncientElf::Init(uint32_t activityId)
{
	GActivity::Init(activityId);
}

void GActivityAncientElf::UnInit()
{
	GActivity::UnInit();
	OnActivityStop();
}

bool GActivityAncientElf::Update()
{
	if (IsRuning())
	{
		OnPlanDestory();
	}
	return true;
}

void GActivityAncientElf::OnActivityStart()
{
	//先清空数据
	Clear();
	//读取lua配置
	if (!g_GetGActivityMgr()->LuaGetAncientElfCfg(m_cfg,m_collegaLev))
	{
		m_cfg.clear();
		return;
	}
	g_GetTimerAxis()->KillTimer(ETimer_ID_Check, this);
	g_GetTimerAxis()->SetTimer(ETimer_ID_Check, 1 * 1000, this);
	//怪物死亡事件
	g_GetEvent()->Subscribe(this, EVENT_CREATURE_DEAD, 0, CREATURE_MONSTER, "GActivityAncientElf");
	//位面销毁事件
	g_GetEvent()->Subscribe(this, EVENT_PLANE_CLOSE, 0, CREATURE_PLAYER, "GActivityAncientElf");
}



void GActivityAncientElf::OnActivityStop()
{
	g_GetEvent()->UnSubscribeAll(this);
	g_GetTimerAxis()->KillAllTimer(this);
	//
	OnPlanDestory();
	//
	RecycleNpcAndMonster();
	//活动结束
	Clear();
	ClearUnionParam();
}


void  GActivityAncientElf::OnTimer(uint32_t nTimerID)
{
	switch (nTimerID)
	{
	case ETimer_ID_Check:
		{
			//先检查需要删除的NPC
			CheckDelNpc();
			//刷新
			CheckFresh();
		}
		break;
	}
}

void GActivityAncientElf::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{
	switch (nEventID)
	{
	case EVENT_CREATURE_DEAD:
		{
			if (nLen < (int32_t)sizeof(DieEvent))
			{
				return;
			}
			DieEvent *pDieEvent = (DieEvent*)pContext;
			if (pDieEvent->sceneId != m_sceneId)
			{
				return;
			}
			SET_UINT64 setCid;
			setCid.clear();
			if (pDieEvent->planUid > 0) //位面怪
			{
				uint64_t npcCid = GetPlanRelate(pDieEvent->planUid);
				AncientElfNpcState *pNpcState = GetNpc(npcCid);
				if (nullptr != pNpcState)
				{
					//这里处理位面怪物掉落
					OnMonsDrop(pDieEvent);

					//这里判断位面内怪物是否都死亡,
					//怪物都死亡了,直接移除位面，移除NPC
					bool ballDie = true;
					VEC_UINT64 vecCreature = g_GetPlaneMgr()->GetPlaneNoPlayerList(pDieEvent->planUid);
					VEC_UINT64::iterator iter = vecCreature.begin();
					for (; iter != vecCreature.end(); ++iter)
					{
						Monster *pCreature = GetSceneMonster((*iter));
						if (nullptr != pCreature)
						{
							if (!pCreature->IsDead())
							{
								ballDie = false;
							}
						}
					}

					VEC_UINT64 vecPlayer = g_GetPlaneMgr()->GetPlanePlayerList(pDieEvent->planUid);
					SET_UINT64 setChar;
					VEC_UINT64::iterator iterEx = vecPlayer.begin();
					for (; iterEx != vecPlayer.end(); ++iterEx)
					{
						setChar.insert((*iterEx));
					}
					//通知追踪栏数据更新
					MultiTrackProto trackProto;
					TrackProtoInfo *proto = trackProto.add_track_info();
					if (nullptr != proto)
					{
						proto->set_mons_id(pDieEvent->monsterId);
						proto->set_mons_num(pDieEvent->count);
					}
					g_GetGActivityMgr()->NotifyUpdateTrack(setChar, PRSTE_ANCIENT_ELF, trackProto);

					if (ballDie)
					{
						LogDebugFmtPrint("all monster die...monsid:%u,monscid:%lu,killercid:%lu, planuid:%lu, npcCid:%lu ", pDieEvent->monsterId, pDieEvent->nCid, pDieEvent->killerCid, pDieEvent->planUid, npcCid);
						AddWaitPlan(pDieEvent->planUid);
					}
					//活跃度处理
					setCid.insert(pDieEvent->killerCid);

					//参加活动
					Participating(pDieEvent->killerCid);
				}
			}
			else
			{
				AnCientElfMonsState *pMonsState = GetMons(pDieEvent->nCid);
				if (nullptr != pMonsState)
				{
					m_elfNumAry[pMonsState->elfType]++;
					//移除怪物
					DelMons(pDieEvent->nCid);

					//这里处理怪物掉落
					OnMonsDrop(pDieEvent);

					//活跃度处理
					setCid.insert(pDieEvent->killerCid);

					//参加活动
					Participating(pDieEvent->killerCid);
				}
			}
			if (setCid.size() > 0)
			{
				AddHuoyue(setCid);
			}
		}
		break;
	case EVENT_PLANE_CLOSE:
		{
			if (nLen < (int32_t)sizeof(PlaneCloseEvent))
			{
				return;
			}
			PlaneCloseEvent *pEvent = (PlaneCloseEvent*)pContext;
			if (pEvent->planeID > 0)
			{
				uint64_t npcCid = GetPlanRelate(pEvent->planeID);
				if (npcCid > 0)
				{
					AncientElfNpcState *pNpcState = GetNpc(npcCid);
					if (nullptr != pNpcState)
					{
						//移除等待销毁的位面
						DelWaitPlan(pEvent->planeID);
						//位面关闭，绑定的NPC对话状态解除//位面关闭，npc回复到倒计时状态
						pNpcState->state = ACT_NPC_STATE_NONE;
						pNpcState->talkCid = 0;
						//通知前端NPC状态
						ActivityNotifyNpcState rsp;
						rsp.set_state_type(ACT_NPC_STATE_TYPE_UPDATE);
						ActMultNpcStateProto *proto = rsp.mutable_state();
						SetNpcStateProto(*proto, *pNpcState);
						//通知NPC状态
						NotifySceneNpcState(rsp);

						//移除位面关联
						DelPlanRelate(pEvent->planeID);

						//位面销毁，通知前端移除追踪
						VEC_UINT64 vecPlayer = g_GetPlaneMgr()->GetPlanePlayerList(pEvent->planeID);
						SET_UINT64 setChar;
						VEC_UINT64::iterator iterEx = vecPlayer.begin();
						for (; iterEx != vecPlayer.end(); ++iterEx)
						{
							setChar.insert((*iterEx));
						}
						g_GetGActivityMgr()->NotifyDelTrack(setChar, PRSTE_ANCIENT_ELF);
					}
				}
			}

		}
		break;
	}
}

void GActivityAncientElf::InitUnionParam(uint32_t unionId, uint32_t sceneId, uint32_t mapId, int32_t unionLev, int32_t averageLev, int32_t collegaLev, int32_t vaultLev)
{
	m_unionId = unionId;
	m_sceneId = sceneId;
	m_mapId = mapId;
	m_lev = unionLev;
	m_averageLev = averageLev;
	m_collegaLev = collegaLev;
}

//玩家进入工会驻地
void GActivityAncientElf::OnEnterUnionHome(CharIDType charId)
{
	Player *pPlayer = g_GetCreatureMgr()->GetPlayer(charId);
	if (nullptr == pPlayer)
	{
		return;
	}
	ActivityNotifyNpcState rsp;
	rsp.set_state_type(ACT_NPC_STATE_TYPE_UPDATE);
	ActMultNpcStateProto *actProto = rsp.mutable_state();
	if (nullptr != actProto)
	{
		AnCientElfNpcMap::iterator iter = m_mapNpc.begin();
		for (; iter != m_mapNpc.end(); ++iter)
		{
			SetNpcStateProto(*actProto, iter->second,charId);
		}
		NotifyPlayerNpcState(pPlayer, rsp);
	}
}

//工会等级更新
void GActivityAncientElf::OnUnionLevUpdate(int32_t unionLev)
{
	m_lev = unionLev;
}
//npc对话
int32_t GActivityAncientElf::TalkToNpc(Player *pPlayer, uint64_t npcCid, int32_t reply, int8_t &type)
{
	_UNUSE(reply);
	type = 0;
	if (nullptr == pPlayer)
	{
		return RET_FAIL;
	}
	if (pPlayer->GetSceneId() != m_sceneId)
	{
		return RET_FAIL;
	}
	bool attendFlag = false;
	CharIDType charId = pPlayer->GetCid();
	AncientElfNpcState *pNpcState = GetNpc(npcCid);
	if (nullptr == pNpcState)
	{
		return RET_ACTIVITY_NPC_NOT_EXIST;
	}
	if (ACT_NPC_STATE_TALK == pNpcState->state || IsDelNpc(npcCid)) //在对话中，或者待删除的NPC 统一返回正在对话中
	{
		//正在对话中
		type = ElfTalk_reply_in_talk;
		//return RET_ACTIVITY_NPC_IN_TALK;
		return RET_SUCCESS;
	}
	Npc *pCreature = GetSceneNpc(npcCid);
	if (nullptr == pCreature)
	{
		LogErrFmtPrint("[logic] GActivityAncientElf::TalkToNpc.....nullptr == pCreature....npc_cid:%lu ", pNpcState->npcCid);
		return RET_FAIL;
	}
	if (ElfSubType_erudite == pNpcState->elfType) //博学的小精灵，答题
	{
		const AnswerAnswerCfgInfo *pAnswerCfg = g_GetAnswerAnswerCfgTable()->GetAnswerAnswerCfgInfo(pNpcState->questionId);
		if (nullptr == pAnswerCfg)
		{
			LogErrFmtPrint("[logic] GActivityAncientElf::TalkToNpc.....nullptr == pAnswerCfg.....charid:%lu, questionId:%u ", charId, pNpcState->questionId);
			return RET_FAIL;
		}
		//检查是否已经回答错误
		if (IsAnswerError(pNpcState, charId))
		{
			//已答错
			//return RET_ACTIVITY_ALREADY_ANSWER_ERROR;
			type = ElfTalk_reply_already_answer_error;
			return RET_SUCCESS;
		}
		//
		VEC_UINT32 vecAnwer;
		vecAnwer.clear();
		vecAnwer.push_back(reply);
		VEC_UINT32 vecRight;
		if (!g_GetAnswerMgr()->Answer(pNpcState->questionId, vecAnwer, vecRight))
		{
			AnswerError(pNpcState, pPlayer);
			//答案错误
			//return RET_ACTIVITY_ANSWER_ERROR;
			type = ElfTalk_reply_answer_error;
			return RET_SUCCESS;
		}
		//参加的标记
		attendFlag = true;
		//答对了，增加奖励
		AddAnswerReward(pPlayer);
		type = ElfTalk_reply_answer_sucess;
		//回答正确，NPC消失,添加到待删除的队列
		AddDelNpc(npcCid);
		//NpcDie(pNpcState->npcCid, pNpcState->elfType, true);
	}
	else if (ElfSubType_greed == pNpcState->elfType) //贪婪的小精灵
	{
		if (ACT_REPLY_NPC_GIVE_MONEY == reply) //给予金币
		{
			if (pPlayer->GetAttr(C_GOLD) < pNpcState->giveMoney)
			{
				//金币不足
				//return RET_MONEY_LACK;
				type = ElfTalk_reply_give_money_fail;
				return RET_SUCCESS;
			}
			//添加奖励
			int32_t ret = AddGiveGoldReward(pPlayer);
			if (RET_SUCCESS != ret)
			{
				return ret;
			}
			//参加的标记
			attendFlag = true;
			//
			type = ElfTalk_reply_give_money_sucess;
			//扣除金币
			//pPlayer->AddAttr(C_GOLD, -pNpcState->giveMoney, true);
			pPlayer->AddSourceAttr(C_GOLD, -pNpcState->giveMoney, true, S_MISSION);
			//NPC 消失 添加到待删除的队列
			//NpcDie(pNpcState->npcCid, pNpcState->elfType, true);
			AddDelNpc(npcCid);
		}
		else if (ACT_REPLY_NPC_KILL_MONS == reply) //小贼看打
		{
			//创建位面
			if (!FreshPlanMonster(pNpcState->npcCid, pCreature->GetPos(), pNpcState->areaId, charId))
			{
				return RET_FAIL;
			}			
			//成功
			type = ElfTalk_reply_kill_mons_sucess;
		}
		else
		{
			return RET_FAIL;
		}
	}
	else
	{
		return RET_FAIL;
	}
	//成功，设置NPC对话状态
	pNpcState->state = ACT_NPC_STATE_TALK;
	pNpcState->talkCid = charId;

	//
	ActivityNotifyNpcState rsp;
	rsp.set_state_type(ACT_NPC_STATE_TYPE_UPDATE);
	ActMultNpcStateProto *proto = rsp.mutable_state();
	SetNpcStateProto(*proto, *pNpcState);
	NotifySceneNpcState(rsp);

	//活跃度处理
	SET_UINT64 setCid;
	setCid.insert(charId);
	AddHuoyue(setCid);

	//参加活动
	if (attendFlag)
	{
		Participating(charId);
	}

	//
	return RET_SUCCESS;
}


int32_t GActivityAncientElf::GetNpcNum(int8_t elfType)				//根据类型获取NPC数量
{
	int32_t count = 0;
	AnCientElfNpcMap::iterator iter = m_mapNpc.begin();
	for (; iter != m_mapNpc.end(); ++iter)
	{
		if (elfType == iter->second.elfType)
		{
			count++;
		}
	}
	return count;
}

void GActivityAncientElf::GetCanFreshNpcArea(int8_t elfType, SET_UINT32 &setArea)	//根据npc类型获取可刷新区域
{
	const SET_UINT32 *pSetAllArea = nullptr;
	if (ElfSubType_erudite == elfType)
	{
		pSetAllArea = &m_cfg.eruditeElf.setArea;
	}
	else if (ElfSubType_greed == elfType)
	{
		pSetAllArea = &m_cfg.greedElf.setArea;
	}
	if (nullptr != pSetAllArea)
	{
		SET_UINT32::const_iterator iter = pSetAllArea->begin();
		for (; iter != pSetAllArea->end(); ++iter)
		{
			if (nullptr == GetAreaNpcByType((*iter), elfType))
			{
				setArea.insert((*iter));
			}
		}
	}
}

void GActivityAncientElf::GetCanFreshMonsArea(int8_t elfType, SET_UINT32 &setArea) 	//根据monster类型获取可刷新区域
{
	const SET_UINT32 *pSetAllArea = nullptr;
	if (ElfSubType_irritable == elfType)
	{
		pSetAllArea = &m_cfg.irritableElf.setArea;
	}
	else if (ElfSubType_trouble == elfType)
	{
		pSetAllArea = &m_cfg.troubleElf.setArea;
	}
	else if (ElfSubType_greed == elfType)
	{
		pSetAllArea = &m_cfg.greedElf.setArea;
	}
	else if (ElfSubType_sensitive == elfType)
	{
		pSetAllArea = &m_cfg.sensitiveElf.setArea;
	}
	if (nullptr != pSetAllArea)
	{
		SET_UINT32::const_iterator iter = pSetAllArea->begin();
		for (; iter != pSetAllArea->end(); ++iter)
		{
			if (nullptr == GetAreaMonsByType((*iter), elfType))
			{
				setArea.insert((*iter));
			}
		}
	}
}

AncientElfNpcState *GActivityAncientElf::GetAreaNpcByType(uint32_t areaId, int8_t elfType)	//根据类型获取区域NPC
{
	AnCientElfNpcMap::iterator iter = m_mapNpc.begin();
	for (; iter != m_mapNpc.end(); ++iter)
	{
		if (iter->second.areaId == areaId && iter->second.elfType == elfType)
		{
			return &iter->second;
		}
	}
	return nullptr;
}

AnCientElfMonsState *GActivityAncientElf::GetAreaMonsByType(uint32_t areaId, int8_t elfType)	//根据类型获取区域怪
{
	AnCientElfMonsMap::iterator iter = m_mapMons.begin();
	for (; iter != m_mapMons.end(); ++iter)
	{
		if (iter->second.areaId == areaId && iter->second.elfType == elfType)
		{
			return &iter->second;
		}
	}
	return nullptr;
}

AncientElfNpcState *GActivityAncientElf::GetNpc(uint64_t npcCid)		//获取NPC状态信息
{
	AnCientElfNpcMap::iterator iter = m_mapNpc.find(npcCid);
	return (iter != m_mapNpc.end()) ? &iter->second : nullptr;
}

AnCientElfMonsState *GActivityAncientElf::GetMons(uint64_t monsCid)	//获取monster状态信息
{
	AnCientElfMonsMap::iterator iter = m_mapMons.find(monsCid);
	return (iter != m_mapMons.end()) ? &iter->second : nullptr;
}

void GActivityAncientElf::DelNpc(uint64_t npcCid)	//移除npc
{
	m_mapNpc.erase(npcCid);
}

void GActivityAncientElf::DelMons(uint64_t monsCid)	//移除monster
{
	m_mapMons.erase(monsCid);
}

void GActivityAncientElf::AddNpc(AncientElfNpcState &npcState)	//添加NPC
{
	m_mapNpc[npcState.npcCid] = npcState;
}

void GActivityAncientElf::AddMons(AnCientElfMonsState &monsState)	//添加monster
{
	m_mapMons[monsState.monsCid] = monsState;
}


void GActivityAncientElf::NpcNum(int32_t &erudite, int32_t &greed)		//npc数量
{
	erudite = 0;
	greed = 0;
	AnCientElfNpcMap::iterator iter = m_mapNpc.begin();
	for (; iter != m_mapNpc.end(); ++iter)
	{
		if (ElfSubType_erudite == iter->second.elfType)
		{
			erudite++;
		}
		else if (ElfSubType_greed == iter->second.elfType)
		{
			greed++;
		}
	}
}

void GActivityAncientElf::MonsNum(int32_t &irritable, int32_t &trouble, int32_t &sensitive) //mons 数量
{
	irritable = 0;
	trouble = 0;
	sensitive = 0;
	AnCientElfMonsMap::iterator iter = m_mapMons.begin();
	for (; iter != m_mapMons.end(); ++iter)
	{
		if (ElfSubType_irritable == iter->second.elfType)
		{
			irritable++;
		}
		else if (ElfSubType_trouble == iter->second.elfType)
		{
			trouble++;
		}
		else if (ElfSubType_sensitive == iter->second.elfType)
		{
			sensitive++;
		}
	}
}

void GActivityAncientElf::NotifyPlayerNpcState(Player *pPlayer, ActivityNotifyNpcState &rsp)
{
	if (nullptr == pPlayer || !rsp.has_state())
	{
		return;
	}
	const ActMultNpcStateProto proto = rsp.state();
	if (proto.info_size() > 0)
	{
		pPlayer->SendDataToClient(EMODULE_ID_ACTIVITY, LOGIC_TO_CLIENT_ACTIVITY_NOTIFY_NPC_STATE, &rsp);
	}	
}

void GActivityAncientElf::NotifySceneNpcState(ActivityNotifyNpcState &rsp)
{
	if (rsp.has_state())
	{
		const ActMultNpcStateProto proto = rsp.state();
		if (proto.info_size() > 0)
		{
			IDuplicate *pDuplicate = g_GetDuplicateMgr()->GetDuplicate(m_sceneId);
			if (nullptr != pDuplicate)
			{
				pDuplicate->BroadCastData(EMODULE_ID_ACTIVITY, LOGIC_TO_CLIENT_ACTIVITY_NOTIFY_NPC_STATE, &rsp);
			}
		}
	}
}

void GActivityAncientElf::SetNpcStateProto(ActMultNpcStateProto &rsp, AncientElfNpcState &npcState)
{
	ActNpcStateProto *proto = rsp.add_info();
	if (nullptr != proto)
	{
		proto->set_npc_cid(npcState.npcCid);
		proto->set_act_type(GetType());
		proto->set_npc_type(npcState.elfType);
		proto->set_state(npcState.state);
		proto->set_question_id(npcState.questionId);
		proto->set_give_money(npcState.giveMoney);
	}
}

void GActivityAncientElf::SetNpcStateProto(ActMultNpcStateProto &rsp, AncientElfNpcState &npcState, CharIDType cid)
{
	ActNpcStateProto *proto = rsp.add_info();
	if (nullptr != proto)
	{
		proto->set_npc_cid(npcState.npcCid);
		proto->set_act_type(GetType());
		proto->set_npc_type(npcState.elfType);
		proto->set_state(npcState.state);
		if (IsAnswerError(&npcState,cid))
		{
			proto->set_state(ACT_NPC_STATE_ANSWER_ERROR);
		}
		proto->set_question_id(npcState.questionId);
		proto->set_give_money(npcState.giveMoney);
	}
}

void GActivityAncientElf::NotifyNpcDie(SET_UINT64 &setDie)
{
	if (setDie.size() <= 0)
	{
		return;
	}
	IDuplicate *pDuplicate = g_GetDuplicateMgr()->GetDuplicate(m_sceneId);
	if (nullptr != pDuplicate)
	{
		ActivityNotifyNpcDie notify;
		SET_UINT64::iterator iter = setDie.begin();
		for (; iter != setDie.end(); ++iter)
		{
			notify.add_npc_lst((*iter));
		}
		pDuplicate->BroadCastData(EMODULE_ID_ACTIVITY, LOGIC_TO_CLIENT_ACTIVITY_NOTIFY_NPC_DEAD, &notify);
	}
}

bool GActivityAncientElf::FreshPlanMonster(uint64_t npcCid,Point3<float> midPos, uint32_t areaId, CharIDType charId) //刷新位面怪
{
	//
	VecPoint3 vecPos;
	vecPos.clear();
	FindBrushPos(midPos, 1, vecPos);
	if (vecPos.size() < 1)
	{
		LogErrFmtPrint("[logic] GActivityAncientElf::FreshPlanMonster....vecPos.size() < 1...");
		return false;
	}
	//只有贪婪的NPC才会触发位面怪
	VEC_UINT32 vecNpc;
	vecNpc.clear();
	uint64_t planUid = g_GetPlaneMgr()->CreatePlane(charId, vecNpc);
	if (planUid <= 0)
	{
		return false;
	}
	//
	//Point3<float> pos = g_GetMapLocationCfg()->RandPosInArea(areaId);
	MonsterExtendInfo extendInfo;
	extendInfo.set_level(m_averageLev);
	Point3<float> curDir = Point3<float>(0, 0, 1);
	Point3<float> pos = (*vecPos.begin());
	MonsCreateParam createParam;
	createParam.createType = EMonsCreateType_Activity;
	createParam.createTypeVal = GetId();
	Monster *pMonster = g_GetCreatureMgr()->CreateMonster(m_cfg.greedElf.freshMonsId, m_sceneId, pos, createParam, curDir, -1, &extendInfo);
	if (nullptr != pMonster)
	{
		LogDebugFmtPrint("[logic] GActivityAncientElf::FreshPlanMonster....CreateMonster....npccid:%lu,areaid:%u, sceneid:%u, mapid:%u, monscid:%lu,pos:[%f,%f,%f] ", npcCid, areaId, m_sceneId, m_mapId, pMonster->GetCid(),pos.x,pos.y,pos.z);
		//添加到位面中
		g_GetPlaneMgr()->AddCreature(planUid, pMonster->GetCid());
		//添加位面关联
		AddPlanRelate(planUid, npcCid);
		//添加追踪栏数据
		SET_UINT64 setChar;
		setChar.insert(charId);
		MultiTrackProto trackProto;
		TrackProtoInfo *proto = trackProto.add_track_info();
		if (nullptr != proto)
		{
			proto->set_mons_id(m_cfg.greedElf.freshMonsId);
			proto->set_mons_num(1);
		}
		g_GetGActivityMgr()->NotifyAddTrack(setChar, PRSTE_ANCIENT_ELF, trackProto);

		return true;
	}
	//失败，玩家离开位面
	g_GetPlaneMgr()->LeavePlane(charId);
	//
	return false;
}

void GActivityAncientElf::AddPlanRelate(uint64_t planUid, uint64_t npcCid)
{
	m_mapPlanRelate[planUid] = npcCid;
}

void GActivityAncientElf::DelPlanRelate(uint64_t planUid)
{
	m_mapPlanRelate.erase(planUid);
}

uint64_t GActivityAncientElf::GetPlanRelate(uint64_t planUid)
{
	MAP_UINT64_UINT64::iterator iter = m_mapPlanRelate.find(planUid);
	return (iter != m_mapPlanRelate.end()) ? iter->second : 0;
}


void GActivityAncientElf::NpcDie(uint64_t npcCid, int8_t elfType, bool notify)	//npc死亡
{
	//结束,npc先离开场景
	Npc *pNpc = GetSceneNpc(npcCid);
	if (nullptr != pNpc && pNpc->LeaveScene())  //离开场景，设置销毁状态
	{
		g_GetCreatureMgr()->Destory(pNpc);
	}
	//移除NPC
	DelNpc(npcCid);
	//记录精灵NPC刷新的数量
	m_elfNumAry[elfType]++;
	if (notify)
	{
		SET_UINT64 setDie;
		setDie.clear();
		setDie.insert(npcCid);
		NotifyNpcDie(setDie);
	}
}

uint32_t GActivityAncientElf::RandQuestionId() //随机一个题目ID
{
	uint32_t questionId = 0;
	int32_t queSize = m_cfg.eruditeElf.setQuestion.size();
	if (queSize > 0)
	{
		int32_t rndNum = Random(queSize);
		SET_UINT32::iterator iter = m_cfg.eruditeElf.setQuestion.begin();
		for (; iter != m_cfg.eruditeElf.setQuestion.end(); ++iter)
		{
			if (rndNum <= 0)
			{
				questionId = (*iter);
				break;
			}
			else
			{
				rndNum -= 1;
			}
		}
	}
	return questionId;
}

int32_t GActivityAncientElf::RandMoney()	//随机一个给予金币数量
{
	int32_t money = (int32_t)Random(1,m_cfg.greedElf.giveGold);
	return money;
}

void GActivityAncientElf::CheckDelNpc()	//检查需要删除的NPC
{
	SET_UINT64 setDie;
	setDie.clear();
	uint64_t curTime = g_GetGlobalServerTime()->UnixSec();
	MAP_UINT64_UINT64::iterator iter = m_mapDelNpc.begin();
	while (iter != m_mapDelNpc.end())
	{
		if (curTime - iter->second >= ENpc_Talk_ContiSec)
		{
			AncientElfNpcState *pNpcState = GetNpc(iter->first);
			if (nullptr != pNpcState)
			{
				//
				NpcDie(pNpcState->npcCid, pNpcState->elfType, false);
				//
				setDie.insert(iter->first);
			}
			//移除
			iter = m_mapDelNpc.erase(iter);
		}
		else
		{
			++iter;
		}
	}
	NotifyNpcDie(setDie);
}

void GActivityAncientElf::CheckFresh() //检查刷新
{
	int32_t erudite = 0;
	int32_t greed = 0;
	int32_t irritable = 0;
	int32_t trouble = 0;
	int32_t sensitive = 0;
	NpcNum(erudite, greed);
	MonsNum(irritable, trouble, sensitive);
	//
	SET_UINT32 setArea;
	ActivityNotifyNpcState rsp;
	rsp.set_state_type(ACT_NPC_STATE_TYPE_UPDATE);
	ActMultNpcStateProto *mutproto = rsp.mutable_state();
	//刷新博学的小精灵
	if (m_elfNumAry[ElfSubType_erudite] < m_cfg.eruditeElf.maxNum && m_elfFreshNumAry[ElfSubType_erudite] < m_cfg.eruditeElf.maxNum && erudite < m_cfg.eruditeElf.curNum)
	{
		int32_t freshnum = m_cfg.eruditeElf.curNum - erudite;
		setArea.clear();
		GetCanFreshNpcArea(ElfSubType_erudite, setArea);
		if ((int32_t)setArea.size() >= freshnum)
		{
			for (int32_t i = 0; i < freshnum; ++i)
			{
				SET_UINT32::iterator iter = setArea.begin();
				uint32_t areaId = (*iter);
				Point3<float> pos = g_GetMapLocationCfg()->RandPosInArea(areaId);
				Npc *pNpc = g_GetCreatureMgr()->CreateNpc(m_cfg.eruditeElf.cfgId, m_sceneId, pos);
				if (nullptr != pNpc)
				{
					AncientElfNpcState npcState;
					npcState.elfType = ElfSubType_erudite;
					npcState.areaId = areaId;
					npcState.npcCid = pNpc->GetCid();
					npcState.startTime = g_GetGlobalServerTime()->UnixSec();
					//博学的小精灵随机一个题目ID
					npcState.questionId = RandQuestionId();
					//
					AddNpc(npcState);
					//
					m_elfFreshNumAry[ElfSubType_erudite]++;
					//
					setArea.erase(iter);
					//
					SetNpcStateProto(*mutproto, npcState);
					//
					LogDebugFmtPrint("[logic] GActivityAncientElf::CheckFresh()...erudite npc...npc_cid:%lu, m_unionId:%u, sceneid:%u, mapid:%u, pos:[%f,%f,%f]", pNpc->GetCid(),m_unionId,m_sceneId,m_mapId,pos.x,pos.y,pos.z);
				}
			}
		}
	}

	//贪婪的小精灵
	if (m_elfNumAry[ElfSubType_greed] < m_cfg.greedElf.maxNum && m_elfFreshNumAry[ElfSubType_greed] < m_cfg.greedElf.maxNum &&  greed < m_cfg.greedElf.curNum)
	{
		int32_t freshnum = m_cfg.greedElf.curNum - greed;
		setArea.clear();
		GetCanFreshNpcArea(ElfSubType_greed, setArea);
		if ((int32_t)setArea.size() >= freshnum)
		{
			for (int32_t i = 0; i < freshnum; ++i)
			{
				SET_UINT32::iterator iter = setArea.begin();
				uint32_t areaId = (*iter);
				Point3<float> pos = g_GetMapLocationCfg()->RandPosInArea(areaId);
				Npc *pNpc = g_GetCreatureMgr()->CreateNpc(m_cfg.greedElf.cfgId, m_sceneId, pos);
				if (nullptr != pNpc)
				{
					AncientElfNpcState npcState;
					npcState.elfType = ElfSubType_greed;
					npcState.areaId = areaId;
					npcState.npcCid = pNpc->GetCid();
					npcState.startTime = g_GetGlobalServerTime()->UnixSec();
					//贪婪的小精灵需要随机一个金币
					npcState.giveMoney = RandMoney();
					//
					AddNpc(npcState);
					//
					m_elfFreshNumAry[ElfSubType_greed]++;
					//
					setArea.erase(iter);
					//
					SetNpcStateProto(*mutproto, npcState);
					//
					LogDebugFmtPrint("[logic] GActivityAncientElf::CheckFresh()...greed npc...npc_cid:%lu, m_unionId:%u, sceneid:%u, mapid:%u, pos:[%f,%f,%f]", pNpc->GetCid(), m_unionId, m_sceneId, m_mapId, pos.x, pos.y, pos.z);
				}
			}
			
		}
	}

	NotifySceneNpcState(rsp);

	//暴躁的小精灵
	if (m_elfNumAry[ElfSubType_irritable] < m_cfg.irritableElf.maxNum && m_elfFreshNumAry[ElfSubType_irritable] < m_cfg.irritableElf.maxNum && irritable < m_cfg.irritableElf.curNum)
	{
		int32_t freshnum = m_cfg.irritableElf.curNum - irritable;
		setArea.clear();
		GetCanFreshMonsArea(ElfSubType_irritable, setArea);
		if ((int32_t)setArea.size() >= freshnum)
		{
			for (int32_t i = 0; i < freshnum; ++i)
			{
				SET_UINT32::iterator iter = setArea.begin();
				uint32_t areaId = (*iter);
				Point3<float> pos = g_GetMapLocationCfg()->RandPosInArea(areaId);
				MonsterExtendInfo extendInfo;
				extendInfo.set_level(m_averageLev);
				Point3<float> curDir = Point3<float>(0, 0, 1);
				MonsCreateParam createParam;
				createParam.createType = EMonsCreateType_Activity;
				createParam.createTypeVal = GetId();
				Monster *pMonster = g_GetCreatureMgr()->CreateMonster(m_cfg.irritableElf.cfgId, m_sceneId, pos, createParam,curDir, -1, &extendInfo);
				if (nullptr != pMonster)
				{
					AnCientElfMonsState monsState;
					monsState.elfType = ElfSubType_irritable;
					monsState.areaId = areaId;
					monsState.monsCid = pMonster->GetCid();
					//
					AddMons(monsState);
					//
					m_elfFreshNumAry[ElfSubType_irritable]++;
					//
					setArea.erase(iter);
					//
					LogDebugFmtPrint("[logic] GActivityAncientElf::CheckFresh()...irritableElf monster...mons_cid:%lu, m_unionId:%u, sceneid:%u, mapid:%u, pos:[%f,%f,%f]", pMonster->GetCid(), m_unionId, m_sceneId, m_mapId, pos.x, pos.y, pos.z);
				}
			}
			
		}
	}

	//捣蛋的小精灵
	if (m_elfNumAry[ElfSubType_trouble] < m_cfg.troubleElf.maxNum && m_elfFreshNumAry[ElfSubType_trouble] < m_cfg.troubleElf.maxNum && trouble < m_cfg.troubleElf.curNum)
	{
		int32_t freshnum = m_cfg.troubleElf.curNum - trouble;
		setArea.clear();
		GetCanFreshMonsArea(ElfSubType_trouble, setArea);
		if ((int32_t)setArea.size() >= freshnum)
		{
			for (int32_t i = 0; i < freshnum; ++i)
			{
				SET_UINT32::iterator iter = setArea.begin();
				uint32_t areaId = (*iter);
				Point3<float> pos = g_GetMapLocationCfg()->RandPosInArea(areaId);
				MonsterExtendInfo extendInfo;
				extendInfo.set_level(m_averageLev);
				Point3<float> curDir = Point3<float>(0, 0, 1);
				MonsCreateParam createParam;
				createParam.createType = EMonsCreateType_Activity;
				createParam.createTypeVal = GetId();
				Monster *pMonster = g_GetCreatureMgr()->CreateMonster(m_cfg.troubleElf.cfgId, m_sceneId, pos, createParam,curDir, -1, &extendInfo);
				if (nullptr != pMonster)
				{
					AnCientElfMonsState monsState;
					monsState.elfType = ElfSubType_trouble;
					monsState.areaId = areaId;
					monsState.monsCid = pMonster->GetCid();
					//
					AddMons(monsState);
					//
					m_elfFreshNumAry[ElfSubType_trouble]++;
					//
					setArea.erase(iter);
					//
					LogDebugFmtPrint("[logic] GActivityAncientElf::CheckFresh()...troubleElf monster...mons_cid:%lu, m_unionId:%u, sceneid:%u, mapid:%u, pos:[%f,%f,%f]", pMonster->GetCid(), m_unionId, m_sceneId, m_mapId, pos.x, pos.y, pos.z);
				}
			}
			
			
		}
	}

	//敏感的小精灵
	if (m_elfNumAry[ElfSubType_sensitive] < m_cfg.sensitiveElf.maxNum && m_elfFreshNumAry[ElfSubType_sensitive] < m_cfg.sensitiveElf.maxNum && sensitive < m_cfg.sensitiveElf.curNum)
	{
		int32_t freshnum = m_cfg.sensitiveElf.curNum - sensitive;
		setArea.clear();
		GetCanFreshMonsArea(ElfSubType_sensitive, setArea);
		if ((int32_t)setArea.size() >= freshnum)
		{
			for (int32_t i = 0; i < freshnum; ++i)
			{
				SET_UINT32::iterator iter = setArea.begin();
				uint32_t areaId = (*iter);
				Point3<float> pos = g_GetMapLocationCfg()->RandPosInArea(areaId);
				MonsterExtendInfo extendInfo;
				extendInfo.set_level(m_averageLev);
				Point3<float> curDir = Point3<float>(0, 0, 1);
				MonsCreateParam createParam;
				createParam.createType = EMonsCreateType_Activity;
				createParam.createTypeVal = GetId();
				Monster *pMonster = g_GetCreatureMgr()->CreateMonster(m_cfg.sensitiveElf.cfgId, m_sceneId, pos, createParam,curDir, -1, &extendInfo);
				if (nullptr != pMonster)
				{
					AnCientElfMonsState monsState;
					monsState.elfType = ElfSubType_sensitive;
					monsState.areaId = areaId;
					monsState.monsCid = pMonster->GetCid();
					//
					AddMons(monsState);
					//
					m_elfFreshNumAry[ElfSubType_sensitive]++;
					//
					setArea.erase(iter);
					//
					LogDebugFmtPrint("[logic] GActivityAncientElf::CheckFresh()...sensitiveElf monster...mons_cid:%lu, m_unionId:%u, sceneid:%u, mapid:%u, pos:[%f,%f,%f]", pMonster->GetCid(), m_unionId, m_sceneId, m_mapId, pos.x, pos.y, pos.z);
				}
			}
			
		}
	}
}


void GActivityAncientElf::OnMonsDrop(DieEvent *pDieEvent)  //怪物掉落
{
	if (nullptr == pDieEvent)
	{
		return;
	}
	Creature *pDieCreature = GetSceneMonster(pDieEvent->nCid);
	if (nullptr == pDieCreature)
	{
		return;
	}
	Creature *pKillerCreature = GetScenePlayer(pDieEvent->killerCid);
	const MonsterMonsterCfgInfo *pMonsterCfg = g_GetMonsterMonsterCfgTable()->GetMonsterMonsterCfgInfo(pDieEvent->monsterId);
	if (nullptr == pMonsterCfg)
	{
		return;
	}

	SDropSourcePram source;
	source.source = EDropSource_Act;
	source.sourceVal = GetId();
	if (pDieEvent->planUid > 0)
	{
		//位面里面的怪物掉落，都是独立掉落
		g_GetDropMgr()->AddDrop(pKillerCreature, pDieCreature->GetPos(), pMonsterCfg->dropDefault, pMonsterCfg->monsterID, pDieCreature->GetAttr(C_LEVEL), source);
	}
	else
	{
		//野外掉落
		g_GetDropMgr()->AddWildDrop(pKillerCreature, m_sceneId, pDieCreature->GetPos(), pMonsterCfg->dropType, pMonsterCfg->dropDefault, pMonsterCfg->monsterID, pDieCreature->GetAttr(C_LEVEL),source);
	}
}

void GActivityAncientElf::RecycleNpcAndMonster()  //回收所有的NPC和怪物
{
	MAP_UINT64_UINT64::iterator iterPlan = m_mapPlanRelate.begin();
	for (; iterPlan != m_mapPlanRelate.end(); ++iterPlan)
	{
		uint64_t planUid = iterPlan->first;
		VEC_UINT64 vecPlayer = g_GetPlaneMgr()->GetPlanePlayerList(planUid);
		VEC_UINT64::iterator iterPlayer = vecPlayer.begin();
		for (; iterPlayer != vecPlayer.end(); ++iterPlayer)
		{
			g_GetPlaneMgr()->LeavePlane((*iterPlayer));
		}
	}
	m_mapPlanRelate.clear();

	AnCientElfNpcMap::iterator iterNpc = m_mapNpc.begin();
	for (; iterNpc != m_mapNpc.end(); ++iterNpc)
	{
		Npc *pNpc = g_GetCreatureMgr()->GetNpc(iterNpc->first);
		if (nullptr != pNpc)
		{
			if (pNpc->LeaveScene())
			{
				//pNpc->SetDestory();
				g_GetCreatureMgr()->WaitDestory(iterNpc->first);
			}
		}
	}
	m_mapNpc.clear();
	//
	AnCientElfMonsMap::iterator iterMons = m_mapMons.begin();
	for (; iterMons != m_mapMons.end(); ++iterMons)
	{
		Monster *pMonster = g_GetCreatureMgr()->GetMonster(iterMons->first);
		if (nullptr != pMonster)
		{
			if (pMonster->LeaveScene())
			{
				//pMonster->SetDestory();
				g_GetCreatureMgr()->WaitDestory(iterMons->first);
			}
		}
	}
	m_mapMons.clear();
}

void GActivityAncientElf::AddDelNpc(uint64_t npcCid) //添加待删除的NPC
{
	m_mapDelNpc[npcCid] = g_GetGlobalServerTime()->UnixSec();
}

bool GActivityAncientElf::IsDelNpc(uint64_t npcCid)	//是否是待移除的NPC
{
	MAP_UINT64_UINT64::iterator iter = m_mapDelNpc.find(npcCid);
	return (iter != m_mapDelNpc.end()) ? true : false;
}

bool GActivityAncientElf::IsAnswerError(AncientElfNpcState *pNpcState, CharIDType cid)  //是否已经答错过
{
	if (nullptr == pNpcState)
	{
		return false;
	}
	SET_UINT64::iterator iter = pNpcState->setAnswer.find(cid);
	return (iter != pNpcState->setAnswer.end()) ? true : false;
}

void GActivityAncientElf::AnswerError(AncientElfNpcState *pNpcState, Player *pPlayer) //答错题
{
	if (nullptr == pNpcState || nullptr == pPlayer)
	{
		return;
	}
	CharIDType cid = pPlayer->GetCid();
	pNpcState->setAnswer.insert(cid);
	//答错了之后要通知前端NPC状态
	ActivityNotifyNpcState rsp;
	rsp.set_state_type(ACT_NPC_STATE_TYPE_UPDATE);
	ActMultNpcStateProto *actProto = rsp.mutable_state();
	if (nullptr != actProto)
	{
		SetNpcStateProto(*actProto, *pNpcState, cid);
		NotifyPlayerNpcState(pPlayer, rsp);
	}
}

void GActivityAncientElf::FindBrushPos(Point3<float> midPos, int32_t count, VecPoint3 &vecPos)
{
	Scene *pScene = g_GetSceneMgr()->GetScene(m_sceneId);
	if (nullptr != pScene)
	{
		pScene->FindPointLstInRect(midPos, vecPos, 2.0f, 2.0f, count);
	}
}

int32_t GActivityAncientElf::AddGiveGoldReward(Player *pPlayer) //增加给予金币奖励
{
	if (nullptr == pPlayer)
	{
		return RET_FAIL;
	}
	Part *pPart = pPlayer->GetPart(PART_PACKAGE);
	if (nullptr == pPart )
	{
		return RET_FAIL;
	}
	//统计随机的基数
	int32_t rndBase = 0;
	VecGiveRewardCfg::const_iterator iter = m_cfg.greedElf.vecGiveReward.begin();
	for (; iter != m_cfg.greedElf.vecGiveReward.end(); ++iter)
	{
		const GiveRewardCfg stReward = (*iter);
		rndBase = stReward.rate;
	}
	if (rndBase > 0)
	{
		int32_t rndNum = Random(rndBase + 1); // 0 - rndBase
		int32_t nTemp = 0;
		LIST_ITEM lstItem;
		lstItem.clear();
		iter = m_cfg.greedElf.vecGiveReward.begin();
		for (; iter != m_cfg.greedElf.vecGiveReward.end(); ++iter)
		{
			const GiveRewardCfg stReward = (*iter);
			nTemp += stReward.rate;
			if (rndNum <= nTemp)
			{
				SItem item;
				item.nItemID = stReward.itemId;
				item.nNum = Random(stReward.minNum, stReward.maxNum);
				lstItem.push_back(item);
				break;
			}
		}
		SItemSourceParam sourceParam;
		sourceParam.source = S_ACTIVE;
		if (!pPart->AddItem(lstItem, sourceParam))
		{
			return RET_PACKAGE_SPACE_NOT_ENOUGH;
		}
	}
	return RET_SUCCESS;
}

int32_t GActivityAncientElf::AddAnswerReward(Player *pPlayer)  //增加答题奖励
{
	if (nullptr == pPlayer)
	{
		return RET_FAIL;
	}
	int32_t level = pPlayer->GetAttr(C_LEVEL);
	int32_t gold = 0;
	int32_t contri = 0;
	g_GetGActivityMgr()->GetEruditeElfReward(level, gold, contri);
	if (gold > 0)
	{
		//pPlayer->AddAttr(C_GOLD, gold, true);
		pPlayer->AddSourceAttr(C_GOLD, gold, true, S_MISSION);
	}
	if (contri > 0)
	{
		LC_UnionUpdateAttrReq req;
		req.set_charid(pPlayer->GetCid());
		req.set_unioncontri(contri);
		req.set_source(S_ACTIVITY_ANWSER);
		g_GetLogicService()->SendDataToCenter(EMODULE_ID_UNION, LOGIC_TO_CENTER_UNION_UPDATE_ATTR, &req);
	}

	return RET_SUCCESS;
}


void GActivityAncientElf::AddHuoyue(SET_UINT64 &setCid)//增加远古精灵活跃度
{
	SET_UINT64::iterator iterCid = setCid.begin();
	for (; iterCid != setCid.end(); ++iterCid)
	{
		Player *pPlayer = GetScenePlayer((*iterCid));
		if (nullptr != pPlayer)
		{
			HuoYueDuPart *pPart = dynamic_cast<HuoYueDuPart*>(pPlayer->GetPart(PART_HUOYUEDU));
			if (nullptr != pPart)
			{
				pPart->AddHuoYueDuRecord(HYDT_ACTIVITY_WIZARD);
			}
		}
	}
}


void GActivityAncientElf::AddWaitPlan(uint64_t planUid)//增加等待销毁的位面
{
	m_setWaitPlan.insert(planUid);
}

void GActivityAncientElf::DelWaitPlan(uint64_t planUid)	//移除等待销毁的位面
{
	m_setWaitPlan.erase(planUid);
}

void GActivityAncientElf::OnPlanDestory()				//销毁位面
{
	SET_UINT64::iterator iter = m_setWaitPlan.begin();
	for (; iter != m_setWaitPlan.end(); ++iter)
	{
		uint64_t planUid = (*iter);
		uint64_t npcCid = GetPlanRelate(planUid);
		AncientElfNpcState *pNpcState = GetNpc(npcCid);
		if (nullptr != pNpcState)
		{
			VEC_UINT64 vecPlayer = g_GetPlaneMgr()->GetPlanePlayerList(planUid);
			SET_UINT64 setChar;
			VEC_UINT64::iterator iterEx = vecPlayer.begin();
			for (; iterEx != vecPlayer.end(); ++iterEx)
			{
				setChar.insert((*iterEx));
			}
			//移除位面关联
			DelPlanRelate(planUid);
			//怪物都死亡了，偷取工会资金失败
			NpcDie(pNpcState->npcCid, pNpcState->elfType, true);
			//						
			VEC_UINT64::iterator iterPlayer = vecPlayer.begin();
			for (; iterPlayer != vecPlayer.end(); ++iterPlayer)
			{
				g_GetPlaneMgr()->LeavePlane((*iterPlayer));
			}

			//位面销毁，通知前端移除追踪
			g_GetGActivityMgr()->NotifyDelTrack(setChar, PRSTE_ANCIENT_ELF);
		}
		else
		{
			LogErrFmtPrint("GActivityAncientElf::OnPlanDestory...planUid:%lu,npcCid:%lu ", planUid, npcCid);
		}
	}
	m_setWaitPlan.clear();
}